#ifndef _LOGIC_INCLUDE_H
#define _LOGIC_INCLUDE_H
//#include <semaphore.h>  //信号量
#include <vector>
#include <list> //用作每个写入磁盘进行保存任务队列
#include "../message_struct/message.pb.h"   //上传的结构
#include <pthread.h>
#include "../../include/inherit_socket.h"
// 文件上传的线程默认数
#define FILE_UPLOAD_THREAD_NUM 5

//文件上传的线程的启停
#define FILE_UPLOADER_THREAD_RUNNING 1   
#define FILE_UPLOADER_THREAD_STOP 0
class transforming_file_info{
public:
    int fd; //该文件的文件描述符
    int file_size;  //文件总大小
    int transformed_bytes; //已经传输的大小 也可作为断点续传的断点发送给客户端

    connection_p con_p;     //用于发送消息后，发送确认给客户端
    int icurrentsequence;       //用于判断连接的失效与否

    //都不需要了
    // std::atomic<int>wait_to_write_pkg;
    // int write_package_num;    //写下的包数量
    // int last_seq_equal;     //上次写入当前的包的seq与write写下的包数量相等时的seq    
   


    //如果还有需要扩展的后续进行扩展
}
;



class file_uploader;

class file_uploader_thread_item{
public:

    pthread_t handler;
    //任务队列
    std::list<file_upload_message*> task_queue;
    //锁
    pthread_mutex_t mutex;
    //条件变量
    pthread_cond_t cond_t;
    //记录线程里打开的fd
    std::map<std::string,transforming_file_info *> fd_map;  //还是放指针吧
    file_uploader * this_file_uploader;
    bool is_running;    //是否启动
    file_uploader_thread_item(file_uploader*this_file_uploader);
    
    ~file_uploader_thread_item(); //进行内存回收
    
    //目前还没有考虑线程结束

};

class file_uploader{
public:

    static file_uploader * get_instance(){
        if(now_file_uploader==nullptr){
            now_file_uploader=new file_uploader();
            static for_file_uploader zz;    //这个只是为了资源的释放
        }
        return now_file_uploader;
    }

    int thread_num;
    //存放全部的断点信息
    std::map<std::string,char> all_info_fd_map;     //存放全部的文件传输的信息，表示每一个正在传输的文件在哪个线程里处理
  
    std::vector<file_uploader_thread_item *> thread_item_list;
    
    
    static void* file_uploader_thread(void *);
    int is_end_file_uploader_thread;    //是否结束上传线程
    void end_file_uploader_thread();    //优雅结束上传线程，用于手动关闭

    
private:
   
    static file_uploader * now_file_uploader;
    file_uploader();
    file_uploader(const file_uploader & l)=delete;
    file_uploader& operator()(const file_uploader & l)=delete;
    class for_file_uploader{
        public:
            ~for_file_uploader(){
                if(file_uploader::now_file_uploader){
                    delete file_uploader::now_file_uploader;
                    file_uploader::now_file_uploader=nullptr;
                }
            }
    };

};
#endif